package com.gking.centerSystem.config;

import com.gking.centerSystem.utils.commonUtil.RandomGenerator;
import lombok.extern.slf4j.Slf4j;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;


/**
 * yml 文件加解密配置
 */
@Configuration
public class JasyptConfig {

    @Bean(name = "CustomJasyptEncryptor")
    public StringEncryptor customJasyptEncryptor() {
        return new CustomJasyptEncryptorUtil();
    }


    /**
     * 加密配置
     */
    public void encryptConfig() {
        CustomJasyptEncryptorUtil customJasyptEncryptorUtil = new CustomJasyptEncryptorUtil();
        customJasyptEncryptorUtil.encryptConfig();
    }

    /**
     * 解密配置
     */
    public void decryptConfig() {
        CustomJasyptEncryptorUtil customJasyptEncryptorUtil = new CustomJasyptEncryptorUtil();
        customJasyptEncryptorUtil.decryptConfig();
    }
}


/**
 * 解密系统配置 yml 文件属性
 */
@Slf4j
@Configuration
class CustomJasyptEncryptorUtil implements StringEncryptor {

    // 加密密钥
    private String SECRET_KEY = "MySecretKey"; // 16位密钥
    // 随机字符串长度
    private final int randomLength = 4;
    //  分块大小
    private final int chunkSize = 20;


    /**
     * 加密
     *
     * @param message 明文
     * @return 密文
     */
    @Override
    public String encrypt(String message) {
        SECRET_KEY = "MySecretKey";
        // 在这里实现你的加密逻辑
        return customEncryption(message);
    }

    /**
     * 解密
     *
     * @param encryptedMessage 密文
     * @return 明文
     */
    @Override
    public String decrypt(String encryptedMessage) {
        SECRET_KEY = "MySecretKey";

        try {
            String filePath = "/www/app/key.png";
            BufferedReader reader = new BufferedReader(new FileReader(filePath));
            String line;
            StringBuilder content = new StringBuilder();
            while ((line = reader.readLine()) != null) content.append(line);
            reader.close();
            SECRET_KEY = content.toString();
        } catch (IOException e) {
            System.err.println("读取文件时发生错误: " + e.getMessage());
        }

        // 在这里实现你的解密逻辑
        return customDecrypt(encryptedMessage);
    }


    /**
     * 加密配置
     */
    public void encryptConfig() {
        SECRET_KEY = "MySecretKey"; // 16位密钥

        // 明文字符串列表
        List<String> valList = new ArrayList<>();

        valList.add("");


        for (String val : valList) {
            log.info("加密后 : {} ", customEncryption(val));
            log.info("\n");
        }

    }


    /**
     * 解密配置
     */
    public void decryptConfig() {
        SECRET_KEY = "MySecretKey"; // 16位密钥

        // 密文字符串列表
        List<String> valList = new ArrayList<>();

        valList.add("");

        for (String val : valList) {
            log.info("解密后 : {} ", customDecrypt(val));
            log.info("\n");
        }
    }


    /**
     * 加密明文
     *
     * @param plainText 明文
     * @return s
     */
    public String customEncryption(String plainText) {
        if (plainText == null) return null;

        String[] strings = splitString(plainText, chunkSize);
        List<String> chunks = new ArrayList<>();

        for (String str : strings) {
            String s = str + RandomGenerator.generateRandomString(randomLength);
            chunks.add(s);
        }

        String encryptionStr = customEncryption(String.join("", chunks), SECRET_KEY);
        return "GKing(" + encryptionStr + ")";
    }


    /**
     * 解密密文
     *
     * @param encryptedText 密文  GKing(fsfasfafsfsfsdfasfsf)
     * @return s
     */
    public String customDecrypt(String encryptedText) {
        if (encryptedText == null) return null;

        String randomStr = encryptedText;
        if (encryptedText.startsWith("GKing(") && encryptedText.endsWith(")")) {
            String firstSub = encryptedText.substring(6);
            randomStr = firstSub.substring(0, firstSub.length() - 1);
        }

        String decrypt = customDecrypt(randomStr, SECRET_KEY);
        String[] strings = splitString(decrypt, chunkSize + randomLength);

        List<String> chunks = new ArrayList<>();
        for (String str : strings) {
            String s = str.substring(0, str.length() - randomLength);
            chunks.add(s);
        }

        return String.join("", chunks);
    }


    /**
     * 切割字符串
     *
     * @param originalString 字符串
     * @param length         切割长度
     * @return l
     */
    private static String[] splitString(String originalString, int length) {
        // 计算需要分割成多少个子串
        int numOfParts = (int) Math.ceil((double) originalString.length() / length);
        String[] splitArray = new String[numOfParts];

        // 遍历原始字符串，按照指定长度分割，并存储到数组中
        for (int i = 0; i < numOfParts; i++) {
            int startIndex = i * length;
            int endIndex = Math.min(startIndex + length, originalString.length());
            splitArray[i] = originalString.substring(startIndex, endIndex);
        }

        return splitArray;
    }


    /**
     * 加密明文
     *
     * @param plainText 明文
     * @param key       密钥
     * @return s
     */
    private String customEncryption(String plainText, String key) {
        if (plainText == null) return null;

        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return e.toString();
        }
    }


    /**
     * 解密密文
     *
     * @param encryptedText 密文
     * @param key           密钥
     * @return s
     */
    private String customDecrypt(String encryptedText, String key) {
        if (encryptedText == null) return null;

        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
            return new String(decryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return e.toString();
        }
    }


}

